<script lang="ts" setup>
import { PropType ,computed,unref,shallowRef,ref,watch,onBeforeUnmount,nextTick,defineProps} from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { i18nChangeLanguage, IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
import { ElMessage } from 'element-plus'
// import { useLocaleStore } from '@/store/modules/locale'
import { getToken } from "@/utils/cache/cookies"
import { propTypes } from "@/utils"
import axios from 'axios'
import CryptoJS from 'crypto-js';
 
const secretKey = import.meta.env.VITE_SECRET_KEY  //这里是自定义的加密秘钥
 
// cosnt file = ref({})
 
defineOptions({ name: 'Editor' })
 
type InsertFnType = (url: string, alt: string, href: string) => void
 
// const localeStore = useLocaleStore()
 
// const currentLocale = computed(() => localeStore.getCurrentLocale)
 
// i18nChangeLanguage(unref(currentLocale).lang) 
 


const props = defineProps({
  editorId: propTypes().string.def('wangeEditor-1'),
  height: propTypes().oneOfType([Number, String]).def('500px'),
  editorConfig: {
    type: Object as PropType<Partial<IEditorConfig>>,
    default: () => undefined
  },
  readonly: propTypes().bool.def(false),
  modelValue: propTypes().string.def('')
})
 
const emit = defineEmits(['change', 'update:modelValue'])
 
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()
 
const valueHtml = ref('')
 
watch(
  () => props.modelValue,
  (val: any) => {
    if (val === unref(valueHtml)) return
    valueHtml.value = val
  },
  {
    immediate: true
  }
)
 
// 监听
watch(
  () => valueHtml.value,
  (val: string) => {
    emit('update:modelValue', val)
  }
)
// 处理上传的文件发生变化
const getSign = (name) => {//加密秘钥的处理，和上传参数一并带去
  let secret = [secretKey.substring(0, 4), secretKey.substring(4, 8), secretKey.substring(8)]
  let str = secret[0] + null + secret[1] + name + secret[2]
  let sign = CryptoJS.MD5(str).toString();
  return sign;
  // 修改 meta 的值
 
}
 
const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor
}
 
 
const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: [
    'uploadVideo', // 排除菜单组，写菜单组 key 的值即可
    "group-video",
  ]
}
 
 
// 编辑器配置
const editorConfig = computed((): IEditorConfig => {
   let data: any = Object.assign(
    {
      placeholder: '请输入内容...',
      readOnly: props.readonly,
      customAlert: (s: string, t: string) => {
        switch (t) {
          case 'success':
            ElMessage.success(s)
            break
          case 'info':
            ElMessage.info(s)
            break
          case 'warning':
            ElMessage.warning(s)
            break
          case 'error':
            ElMessage.error(s)
            break
          default:
            ElMessage.info(s)
            break
        }
      },
      autoFocus: false,
      scroll: true,
      MENU_CONF: {
        ['uploadImage']: {
          server: import.meta.env.VITE_UPLOAD_URL,
          // 单个文件的最大体积限制，默认为 2M
          maxFileSize: 5 * 1024 * 1024,
          // 最多可上传几个文件，默认为 100
          maxNumberOfFiles: 10,
          // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
          allowedFileTypes: ['image/*'],
 
          // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
          meta: { updateSupport: 0 },
          // 将 meta 拼接到 url 参数中，默认 false
          metaWithUrl: true,
 
          // 自定义增加 http  header
          headers: {
            Accept: '*',
            Authorization: 'Bearer ' + getToken(),
            token: getToken()
          },
 
          // 跨域是否传递 cookie ，默认为 false
          withCredentials: true,
 
          // 超时时间，默认为 10 秒
          timeout: 5 * 1000, // 5 秒
 
          // form-data fieldName，后端接口参数名称，默认值wangeditor-uploaded-image
          fieldName: 'file',
 
          // 上传之前触发
          onBeforeUpload(file: File) {
            // console.log('kankansheikuai22222 :>> ');
 
            // for (const key in file) {
            //   handleFileChange(file[key])
            // }
            return file
          },
          // 上传进度的回调函数
          onProgress(progress: number) {
            // progress 是 0-100 的数字
            console.log('progress', progress)
          },
          onSuccess(file: File, res: any) {
            console.log('onSuccess', file, res)
          },
          onFailed(file: File, res: any) {
            alert(res.message)
            console.log('onFailed', file, res)
          },
          onError(file: File, err: any, res: any) {
            alert(err.message)
            console.error('onError', file, err, res)
          },
          // 自定义插入图片
          customInsert(res: any, insertFn: InsertFnType) {
            insertFn(res.data, 'image', res.data)
          },
          async customUpload(file: File, insertFn: InsertFnType) {  // TS 语法,这里是覆盖原生的上传，这里覆盖的原因是我们图片要做一定的加密，但是原生的不能做到携带我们的参数
            // file 即选中的文件
            // 最后插入图片
            // insertFn(url, alt, href)
            console.log('shangchaun :>> ', file, insertFn);
            // let url = import.meta.env.VITE_UPLOAD_URL
            try {
              const response = await axios.post(process.env.NODE_ENV === 'development'?'/api/bg/file/upload':'/bg/file/upload',
                {
                  file: file
                }
                , {
                  headers: {
                    'Content-Type': 'multipart/form-data',
                    'Accept': 'application/json, text/plain, */*',
                  },
                }); // 替换为你的 API 端点和数据
              console.log('POST response:', response.data);
              if (response.data.code != 500) {
                insertFn(response.data.result, response.data.result, response.data.result) // 插入图片，参数：图片 src、alt、href
              } else {
                ElMessage.error(response.data.errMsg)

              }
            } catch (error) {
              console.error('Error posting data:', error);
            }
          }
        },
      },
      uploadImgShowBase64: true
    },
    props.editorConfig || {}
  )
  return {...data}
})
 
const isNumber = (value: any): boolean => {
  return typeof value === 'number' && !isNaN(value);
}

const editorStyle = computed(() => {
  return {
    height: isNumber(props.height) ? `${props.height}px` : props.height
  }
})
// 回调函数
const handleChange = (editor: IDomEditor) => {
  emit('change', editor)
}
 
// 组件销毁时，及时销毁编辑器
onBeforeUnmount(() => {
  const editor = unref(editorRef.value)
 
  // 销毁，并移除 editor
  editor?.destroy()
})
 
const getEditorRef = async (): Promise<IDomEditor> => {
  await nextTick()
  return unref(editorRef.value) as IDomEditor
}
 
defineExpose({
  getEditorRef
})
</script>
 
<template>
  <div class="border-1 border-solid border-[var(--el-border-color)] z-99">
    <!-- 工具栏 -->
    <Toolbar :editor="editorRef" :editorId="editorId" :defaultConfig="toolbarConfig"
      class="border-0 b-b-1 border-solid border-[var(--el-border-color)]" style="position: relative;z-index: 9999;" />
    <!-- 编辑器 -->
    <Editor v-model="valueHtml" :defaultConfig="editorConfig" :editorId="editorId" :style="editorStyle"
      @on-change="handleChange" @on-created="handleCreated" />
  </div>
</template>
 
<style src="@wangeditor/editor/dist/css/style.css"></style>